package com.xiaoq.distribution.endpoint;

import com.alibaba.dubbo.config.annotation.Reference;
import com.xiaoq.BaseEndpoint2B;
import com.xiaoq.apis.sites.ISitesApi;
import com.xiaoq.coms.GenericDataResponse;
import com.xiaoq.coms.GenericListResponse;
import com.xiaoq.coms.GenericResponse;
import com.xiaoq.coms.util.ConstantUtil;
import com.xiaoq.coms.util.IdGenerator;
import com.xiaoq.coms.util.MathUtil;
import com.xiaoq.distribution.entity.*;
import com.xiaoq.distribution.service.*;
import com.xiaoq.distribution.vo.Distributor4SettleVo;
import com.xiaoq.distribution.vo.SettleHistoryVo;
import com.xiaoq.distribution.vo.TicketSettle4SheetVo;
import com.xiaoq.distribution.vo.TicketSettleVo;
import com.xiaoq.order.entity.PayState;
import com.xiaoq.shop.service.ISKUService;
import com.xiaoq.vo.PagingVo;
import io.swagger.annotations.*;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.joda.time.DateTime;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Created by chenjh on 2018/5/29.
 */
@RestController
@RequestMapping(value = "/api/v1/ticketsettle")
@Api(tags={"渠道分销结算管理"})
public class TicketSettleEndpoint extends BaseEndpoint2B {

    @Reference(interfaceClass=ISitesApi.class,check=false,version="1.0.0")
    private ISitesApi sitesApi;

    @Autowired
    private IdGenerator idGenerator;

    @Autowired
    private IDistributorService distributorService;

    @Autowired
    private IDistriTicketService distriTicketService;

    @Autowired
    private ITicketSettleService ticketSettleService;

    @Autowired
    private ISKUService skuService;

    @Autowired
    private ITicketOrderItemService ticketOrderItemService;

    @Autowired
    private ISettleHistoryService settleHistoryService;

    private static final class Distributor4SettleListResponse extends GenericListResponse<Distributor4SettleVo> {}
    private static final class TicketSettle4SheetDataResponse extends GenericDataResponse<TicketSettle4SheetVo> {}
    private static final class SettleHistoryListResponse extends GenericListResponse<SettleHistoryVo> {}


    @ApiOperation(value = "结算管理-列表", notes = "结算管理-列表")
    @ApiResponses({ @ApiResponse(code = 200, response = Distributor4SettleListResponse.class, message = "结算管理-列表") })
    @GetMapping(value = "", produces = { MediaType.APPLICATION_JSON_UTF8_VALUE })
    public ResponseEntity<?> list(HttpServletRequest request) {

        String shopId = getShopId();
        
        List<DistributorEntity> distributorList =  distributorService.getListByShopIdAndAgree(shopId, ConstantUtil.DISTRIBUTION_AGREEMENT);

        List<String> distributorIdList = new ArrayList<>();

        List<Distributor4SettleVo> resultList = new ArrayList<>();
        Distributor4SettleVo distributor4SettleVo;

        if(CollectionUtils.isNotEmpty(distributorList)){
            for (DistributorEntity distributorEntity : distributorList){
                distributorIdList.add(distributorEntity.getId());

                distributor4SettleVo = new Distributor4SettleVo();
                BeanUtils.copyProperties(distributorEntity, distributor4SettleVo);
                resultList.add(distributor4SettleVo);
            }
        }

        List<SettleHistoryEntity> settleHistoryList = settleHistoryService.getSettleHistoryListWithDistriIdList(shopId, distributorIdList,
                ConstantUtil.IS_THE_LATEST_SETTLE);

        Map<String, SettleHistoryEntity> distributorId2SettleHistoryMap = new HashMap<>(resultList.size());
        if(settleHistoryList != null){
            for(SettleHistoryEntity settleHistoryEntity : settleHistoryList){
                distributorId2SettleHistoryMap.put(settleHistoryEntity.getDistributorId(), settleHistoryEntity);
            }
        }

        int resultListSize = resultList.size();
        for (int i = 0; i < resultListSize; i++){
            Distributor4SettleVo distributor4Settle = resultList.get(i);
            SettleHistoryEntity settleHistoryEntity = distributorId2SettleHistoryMap.get(distributor4Settle.getId());
            if(settleHistoryEntity != null){
                double currentSettleMoney = settleHistoryEntity.getCurrentSettleAmount() == null ? 0.0d : settleHistoryEntity.getCurrentSettleAmount();
                distributor4Settle.setCurrentSettleMoney(currentSettleMoney);
                distributor4Settle.setCurrentSettleTime(settleHistoryEntity.getCreatedAt());
            }
        }

        return Distributor4SettleListResponse.listNoCount(resultList);
    }


    @ApiOperation(value = "结算历史记录列表", notes = " 结算历史记录列表")
    @ApiResponses({ @ApiResponse(code = 200, response = SettleHistoryListResponse.class, message = "结算历史记录列表") })
    @GetMapping(value = "/history/{distributorId}", produces = { MediaType.APPLICATION_JSON_UTF8_VALUE })
    public ResponseEntity<?> list4History(HttpServletRequest request,
                                          @PathVariable(value="distributorId") @ApiParam(value="分销商id")String distributorId,
                                          @RequestParam(value="settleBeginTime", required = false) @ApiParam(value="结算开始时间") Long settleBeginTime,
                                          @RequestParam(value="settleEndTime", required = false) @ApiParam(value="结算结束时间") Long settleEndTime,
                                          @ApiParam(value="pn", required=false) @RequestParam(required = false, defaultValue = "1") int pn,
                                          @ApiParam(value="ps", required=false) @RequestParam(required = false, defaultValue = "10") int ps) {
        String shopId = getShopId();
        PagingVo pagingVo = new PagingVo(pn, ps);
        List<SettleHistoryEntity> settleHistoryList = settleHistoryService.getSettleHistoryList(shopId,
                distributorId,
                null,
                settleBeginTime,
                settleEndTime,
                pagingVo);
        long count = settleHistoryService.getSettleHistoryCount(shopId,
                distributorId,
                null,
                settleBeginTime,
                settleEndTime,
                pagingVo);

        List<SettleHistoryVo> resultList = new ArrayList<>();
        SettleHistoryVo settleHistoryVo;
        if(CollectionUtils.isNotEmpty(settleHistoryList)){
            for (SettleHistoryEntity settleHistoryEntity : settleHistoryList){
                settleHistoryVo = new SettleHistoryVo();
                BeanUtils.copyProperties(settleHistoryEntity, settleHistoryVo);
                resultList.add(settleHistoryVo);
            }
        }
        return SettleHistoryListResponse.listAndCount(resultList, count);
    }

    @ApiOperation(value = "某一结算历史记录列表", notes = "某一结算历史记录列表")
    @ApiResponses({ @ApiResponse(code = 200, response = TicketSettle4SheetDataResponse.class, message = "某一结算历史记录列表") })
    @GetMapping(value = "/history/{settleHistoryId}/item", produces = { MediaType.APPLICATION_JSON_UTF8_VALUE })
    public ResponseEntity<?> list4HistoryItem(HttpServletRequest request,@PathVariable(value="settleHistoryId") @ApiParam(value="结算ID")String settleHistoryId) {
        String shopId = getShopId();

        SettleHistoryEntity settleHistoryEntity = settleHistoryService.getById(settleHistoryId);
        TicketSettle4SheetVo ticketSettle4SheetVo = new TicketSettle4SheetVo();
        List<TicketSettleEntity> ticketSettleList = null;
        if(settleHistoryEntity != null){
            BeanUtils.copyProperties(settleHistoryEntity, ticketSettle4SheetVo);
            ticketSettleList = ticketSettleService.getTicketSettleList(settleHistoryId, null);
        }

        List<TicketSettleVo> orderItemList4CreatedOrderSettle = new ArrayList<>();
        List<TicketSettleVo> orderItemList4UseTicketSettle = new ArrayList<>();
        List<TicketSettleVo> orderItemList4RefundOrder = new ArrayList<>();

        if(CollectionUtils.isNotEmpty(ticketSettleList)){
            for(TicketSettleEntity ticketSettleEntity : ticketSettleList){
                Integer settleStatus = ticketSettleEntity.getSettleStatus();

                TicketSettleVo ticketSettleVo = new TicketSettleVo();
                BeanUtils.copyProperties(ticketSettleEntity, ticketSettleVo);

                if(ConstantUtil.SETTLE_STATUS_COMMIT_ORDER.equals(settleStatus)){
                    orderItemList4CreatedOrderSettle.add(ticketSettleVo);
                }else if (ConstantUtil.SETTLE_STATUS_USE.equals(settleStatus)){
                    orderItemList4UseTicketSettle.add(ticketSettleVo);
                }else if(ConstantUtil.SETTLE_STATUS_REFUND_ORDER.equals(settleStatus)){
                    orderItemList4RefundOrder.add(ticketSettleVo);
                }
            }
        }

        ticketSettle4SheetVo.setDealOrderItem(orderItemList4CreatedOrderSettle);
        ticketSettle4SheetVo.setUsedOrderItem(orderItemList4UseTicketSettle);
        ticketSettle4SheetVo.setRefundOrderItem(orderItemList4RefundOrder);

        return TicketSettle4SheetDataResponse.okWithData(ticketSettle4SheetVo);
    }


    @ApiOperation(value = "结算管理-结算", notes = "结算管理-结算")
    @ApiResponses({ @ApiResponse(code = 200, response = TicketSettle4SheetDataResponse.class, message = "结算管理-结算") })
    @GetMapping(value = "/settle/{distributorId}", produces = { MediaType.APPLICATION_JSON_UTF8_VALUE })
    public ResponseEntity<?> settleDistributor(HttpServletRequest request, @PathVariable(value="distributorId") @ApiParam(value="分销商id")String distributorId) {
        String shopId = getShopId();
        DistributorEntity distributorEntity = distributorService.findById(distributorId);
        if(distributorEntity == null){
            return GenericResponse.ng("此分销商不存在");
        }

        if(!StringUtils.equals(distributorEntity.getIsAgree(), ConstantUtil.DISTRIBUTION_AGREEMENT)){
            return GenericResponse.ng("此分销商合同不存在或未通过");
        }

        List<DistriTicketEntity> distriTicketList =  distriTicketService.getDistriTicketList(distributorId, null, ConstantUtil.DISTRIBUTION_AGREEMENT);
        if(CollectionUtils.isEmpty(distriTicketList)){
            return GenericResponse.ng("分销商暂时未签订合同");
        }

        //List<String> ticketIdList = distriTicketList.stream().map(item -> item.getTicketId()).collect(Collectors.toList());

        String settleCycle = distributorEntity.getSettleCycle();
        Integer settleTime = distributorEntity.getSettleTime();

        if(settleTime == null){
            return GenericResponse.ng("结算时间错误");
        }
        //得到上一次结算的时间
        SettleHistoryEntity settleHistoryEntity = settleHistoryService.getByDistributorId(distributorId, ConstantUtil.IS_THE_LATEST_SETTLE);
        DateTime lastSettleDate;

        //查询订单的开始时间
        long settleOrderBeginTime = 0L;
        //查询订单的结束时间
        long settleOrderEndTime = 0L;

        if(StringUtils.equals(settleCycle, ConstantUtil.FIXED_SETTLE_CYCLE_TYPE)){

            if(settleHistoryEntity == null){
                //第一次结算, 取分销商的开始时间作为结算的起点时间
                lastSettleDate = new DateTime(distributorEntity.getCreatedAt()).withDayOfMonth(settleTime);
            }else {
                //以前结算过
                lastSettleDate = new DateTime(settleHistoryEntity.getSettleOrderEndTime());//结算订单的时间指每月5日24点
            }

            DateTime now = new DateTime();
            int nowMonthOfYear = now.getMonthOfYear();
            int nowYear = now.getYear();
            int nowDayOfMonth = now.getDayOfMonth();
            int settleMonthOfYear = lastSettleDate.getMonthOfYear();
            int settleYear = lastSettleDate.getYear();
            int settleDayOfMonth = lastSettleDate.getDayOfMonth();

            if(nowYear > settleYear){ //处理跨年
                if(nowMonthOfYear + 12 - settleMonthOfYear == 1){
                    if(nowDayOfMonth > settleDayOfMonth){

                    }else {
                        return GenericResponse.ng("时间未到，不可以结算");
                    }
                }else if(nowMonthOfYear + 12 - settleMonthOfYear > 1){
                    if(nowDayOfMonth > settleDayOfMonth){

                    }else {
                        //上个月的时间
                        if(nowMonthOfYear == 1){
                            nowMonthOfYear = 12;
                            nowYear = nowYear - 1;
                        }else {
                            nowMonthOfYear = nowMonthOfYear - 1;
                        }
                    }
                }else {
                    return GenericResponse.ng("时间未到，不可以结算");
                }
            }else if(nowYear == settleYear){ // 处理同年
                if(nowMonthOfYear == settleMonthOfYear){
                    if(settleHistoryEntity != null){
                        //本月已结算
                        return GenericResponse.ng("本月已结算");
                    }else {
                        if(nowDayOfMonth < settleDayOfMonth){
                            return GenericResponse.ng("时间未到，不可以结算");
                        }
                    }
                }else if(nowMonthOfYear - settleMonthOfYear > 1){
                    if(nowDayOfMonth > settleDayOfMonth){

                    }else {
                        //上个月的时间
                        nowMonthOfYear = nowMonthOfYear - 1;
                    }
                }else if(nowMonthOfYear - settleMonthOfYear == 1){
                    if(nowDayOfMonth < settleDayOfMonth){
                        return GenericResponse.ng("时间未到，不可以结算");
                    }
                }else {
                    return GenericResponse.ng("结算时间未到，暂不能结算");
                }
            }

            settleOrderBeginTime = lastSettleDate.getMillis();
            settleOrderEndTime = new DateTime(
                    nowYear,
                    nowMonthOfYear,
                    settleTime,
                    23,
                    59).getMillis();
            //整合，返回数据
        }else if(StringUtils.equals(settleCycle, ConstantUtil.NON_FIXED_SETTLE_CYCLE_TYPE)){
            /*
            *  假如今天12号， 下单5天后可结算
            *  第一次结算 假如今天 12号，结算的订单在  12-5 = 7号之前的订单
            *  第二次结算，假如今天20号， 结算的订单在 上一次结算的日期  7号  到 20-5=15 号 产生的订单，即（7号至15号产生的订单）
            * */
            //非固定結算日期，即下单后几日可以结算。｛下单后几日结算，核销结算｝
            DateTime now = new DateTime();

            if(settleHistoryEntity == null){ //第一次结算
                //第一次结算, 取分销商的开始时间作为结算的起点时间
                lastSettleDate = new DateTime(distributorEntity.getCreatedAt());
            }else {
                //
                lastSettleDate = new DateTime(settleHistoryEntity.getSettleOrderEndTime());//结算订单的时间指每月5日24点
            }

            settleOrderBeginTime = lastSettleDate.getMillis();
            settleOrderEndTime = new DateTime(
                    now.getYear(),
                    now.getMonthOfYear(),
                    now.getDayOfMonth(),
                    23,
                    59).minusDays(settleTime).getMillis();
        }else {
            return GenericResponse.ng("未知错误");
        }

        List<TicketOrderItemEntity> orderItemList4CreatedOrderSettle = null;
        List<TicketOrderItemEntity> orderItemList4UseTicketSettle = null;
        List<TicketOrderItemEntity> orderItemList4RefundOrder = null;
        for (DistriTicketEntity distriTicketEntity : distriTicketList){
            String settleType = distriTicketEntity.getBalance();
            String ticketId = distriTicketEntity.getTicketId();
            if(StringUtils.equals(settleType, ConstantUtil.SETTLE_TYPE_4_CREATE_ORDER)){
                //String orderId, String distributorId, String ticketId, Long minCreateTime, Long maxCreateTime,Integer payState
                orderItemList4CreatedOrderSettle = ticketOrderItemService.getOrderItemList4CreatedTicketSettle(null, distributorId, ticketId, settleOrderBeginTime,
                        settleOrderEndTime, PayState.PAID.value());
            }else if (StringUtils.equals(settleType, ConstantUtil.SETTLE_TYPE_4_USE_TICKET)){
                //String shopOrderid, String distributorId, String ticketId, Long minUseTime, Long maxUseTime, Integer payState
                orderItemList4UseTicketSettle = ticketOrderItemService.getOrderItemList4UseTicketSettle(null, distributorId, ticketId,
                        settleOrderBeginTime, settleOrderEndTime, PayState.PAID.value());
            }
        }

        List<TicketSettleVo> ticketSettle4CreatedList = new ArrayList<>(0);
        List<TicketSettleVo> ticketSettle4UseList = new ArrayList<>(0);
        List<TicketSettleVo> ticketSettle4RefundList = new ArrayList<>(0);

        double refundMoney = 0.0d, createOrderMoney = 0.0d, useOrderMoeny = 0.0d;
        //处理退款的订单
        orderItemList4RefundOrder = ticketOrderItemService.getRefundOrderItemList(null, distributorId, null, settleOrderBeginTime, settleOrderEndTime, PayState.REFUNDED.value());

        if(CollectionUtils.isNotEmpty(orderItemList4RefundOrder)){
            ticketSettle4RefundList = new ArrayList<>(orderItemList4RefundOrder.size());
            for (TicketOrderItemEntity ticketOrderItemEntity : orderItemList4RefundOrder){
                refundMoney += ticketOrderItemEntity.getSettleMoney();

                TicketSettleVo ticketSettleVo = new TicketSettleVo();
                BeanUtils.copyProperties(ticketOrderItemEntity, ticketSettleVo);
                ticketSettle4RefundList.add(ticketSettleVo);
            }
        }

        //处理已支付的订单
        if(CollectionUtils.isNotEmpty(orderItemList4CreatedOrderSettle)){
            ticketSettle4CreatedList = new ArrayList<>(orderItemList4CreatedOrderSettle.size());
            for (TicketOrderItemEntity ticketOrderItemEntity : orderItemList4CreatedOrderSettle){
                createOrderMoney += ticketOrderItemEntity.getSettleMoney();

                TicketSettleVo ticketSettleVo = new TicketSettleVo();
                BeanUtils.copyProperties(ticketOrderItemEntity, ticketSettleVo);
                ticketSettle4CreatedList.add(ticketSettleVo);
            }
        }

        //处理核销的数据
        if(CollectionUtils.isNotEmpty(orderItemList4UseTicketSettle)){
            ticketSettle4UseList = new ArrayList<>(orderItemList4UseTicketSettle.size());
            for (TicketOrderItemEntity ticketOrderItemEntity : orderItemList4UseTicketSettle){
                useOrderMoeny += ticketOrderItemEntity.getSettleMoney();

                TicketSettleVo ticketSettleVo = new TicketSettleVo();
                BeanUtils.copyProperties(ticketOrderItemEntity, ticketSettleVo);
                ticketSettle4UseList.add(ticketSettleVo);
            }
        }

        TicketSettle4SheetVo ticketSettle4SheetVo = new TicketSettle4SheetVo();
        ticketSettle4SheetVo.setCurrentSettleAmount(MathUtil.decimal2Digits(createOrderMoney-refundMoney+useOrderMoeny, 2));
        ticketSettle4SheetVo.setDealAmount(MathUtil.decimal2Digits(createOrderMoney, 2));
        ticketSettle4SheetVo.setRefundAmount(MathUtil.decimal2Digits(refundMoney, 2));
        ticketSettle4SheetVo.setRefundOrderItem(ticketSettle4RefundList);
        ticketSettle4SheetVo.setSettleOrderBeginTime(settleOrderBeginTime);
        ticketSettle4SheetVo.setSettleOrderEndTime(settleOrderEndTime);
        ticketSettle4SheetVo.setUsedOrderItem(ticketSettle4UseList);
        ticketSettle4SheetVo.setVerificationAmount(MathUtil.decimal2Digits(useOrderMoeny, 2));
        ticketSettle4SheetVo.setDealOrderItem(ticketSettle4CreatedList);
        return TicketSettle4SheetDataResponse.okWithData(ticketSettle4SheetVo);
    }


    @ApiOperation(value = "保存结算信息", notes = "保存结算信息")
    @ApiResponses({ @ApiResponse(code = 200, response = TicketSettle4SheetDataResponse.class, message = "保存结算信息") })
    @PostMapping(value = "/settle/{distributorId}", produces = { MediaType.APPLICATION_JSON_UTF8_VALUE })
    public ResponseEntity<?> saveSettleResult(HttpServletRequest request,
                                              @PathVariable(value="distributorId") @ApiParam(value="分销商id")String distributorId,
                                              @RequestParam(value="settleOrderBeginTime") @ApiParam(value="结算开始时间") Long settleOrderBeginTime,
                                              @RequestParam(value="settleOrderEndTime") @ApiParam(value="结算结束时间") Long settleOrderEndTime) {
        String shopId = getShopId();
        DistributorEntity distributorEntity = distributorService.findById(distributorId);
        if(distributorEntity == null){
            return GenericResponse.ng("此分销商不存在");
        }

        List<DistriTicketEntity> distriTicketList =  distriTicketService.getDistriTicketList(distributorId, null, ConstantUtil.DISTRIBUTION_AGREEMENT);
        if(CollectionUtils.isEmpty(distriTicketList)){
            return GenericResponse.ng("分销商暂时未签订合同");
        }

        String settleCycle = distributorEntity.getSettleCycle();
        Integer settleTime = distributorEntity.getSettleTime();

        if(settleTime == null){
            return GenericResponse.ng("结算时间错误");
        }

        List<TicketOrderItemEntity> orderItemList4CreatedOrderSettle = null;
        List<TicketOrderItemEntity> orderItemList4UseTicketSettle = null;
        List<TicketOrderItemEntity> orderItemList4RefundOrder;
        double refundMoney = 0.0d, createOrderMoney = 0.0d, useOrderMoeny = 0.0d;

        for (DistriTicketEntity distriTicketEntity : distriTicketList){
            String settleType = distriTicketEntity.getBalance();
            String ticketId = distriTicketEntity.getTicketId();
            if(StringUtils.equals(settleType, ConstantUtil.SETTLE_TYPE_4_CREATE_ORDER)){
                //String orderId, String distributorId, String ticketId, Long minCreateTime, Long maxCreateTime,Integer payState
                orderItemList4CreatedOrderSettle = ticketOrderItemService.getOrderItemList4CreatedTicketSettle(null, distributorId, ticketId, settleOrderBeginTime, settleOrderEndTime, PayState.PAID.value());
            }else if (StringUtils.equals(settleType, ConstantUtil.SETTLE_TYPE_4_USE_TICKET)){
                //String shopOrderid, String distributorId, String ticketId, Long minUseTime, Long maxUseTime, Integer payState
                orderItemList4UseTicketSettle = ticketOrderItemService.getOrderItemList4UseTicketSettle(null, distributorId, ticketId, settleOrderBeginTime, settleOrderEndTime, PayState.PAID.value());
            }
        }

        //处理退款的订单
        orderItemList4RefundOrder = ticketOrderItemService.getRefundOrderItemList(null, distributorId, null, settleOrderBeginTime, settleOrderEndTime, PayState.REFUNDED.value());

        if(CollectionUtils.isEmpty(orderItemList4CreatedOrderSettle) && CollectionUtils.isEmpty(orderItemList4UseTicketSettle)
                && CollectionUtils.isEmpty(orderItemList4RefundOrder)){
            return GenericResponse.ng("没有订单，暂时不能结算");
        }

        //TODO 计算价格， 可通过数据库 sum 查询
        if(CollectionUtils.isNotEmpty(orderItemList4RefundOrder)){
            for (TicketOrderItemEntity ticketOrderItemEntity : orderItemList4RefundOrder){
                refundMoney += ticketOrderItemEntity.getSettleMoney();
            }
        }else {
            orderItemList4RefundOrder = new ArrayList<>(0);
        }

        //处理已支付的订单
        if(CollectionUtils.isNotEmpty(orderItemList4CreatedOrderSettle)){
            for (TicketOrderItemEntity ticketOrderItemEntity : orderItemList4CreatedOrderSettle){
                createOrderMoney += ticketOrderItemEntity.getSettleMoney();
            }
        }else {
            orderItemList4CreatedOrderSettle = new ArrayList<>(0);
        }

        //处理核销的数据
        if(CollectionUtils.isNotEmpty(orderItemList4UseTicketSettle)){
            for (TicketOrderItemEntity ticketOrderItemEntity : orderItemList4UseTicketSettle){
                useOrderMoeny += ticketOrderItemEntity.getSettleMoney();
            }
        }else {
            orderItemList4UseTicketSettle = new ArrayList<>(0);
        }

        //TODO 异步更新订单的结算状态
        SettleHistoryEntity settleHistoryFromDb = settleHistoryService.getByDistributorId(distributorId,
                ConstantUtil.IS_THE_LATEST_SETTLE);

        if(settleHistoryFromDb != null){
            SettleHistoryEntity updateSettleHistory = new SettleHistoryEntity();
            updateSettleHistory.setId(settleHistoryFromDb.getId());
            updateSettleHistory.setTheLatestSettle(ConstantUtil.IS_NOT_THE_LATEST_SETTLE);
            settleHistoryService.updateById(updateSettleHistory);
        }

        long now = System.currentTimeMillis();

        SettleHistoryEntity settleHistoryEntity = new SettleHistoryEntity();
        String settleHistoryId = idGenerator.nextId();
        settleHistoryEntity.setId(settleHistoryId);
        settleHistoryEntity.setDistributorId(distributorId);
        settleHistoryEntity.setDistributorName(distributorEntity.getName());
        settleHistoryEntity.setSettleContact(distributorEntity.getSettleContact());
        settleHistoryEntity.setSettleCycle(settleCycle);
        settleHistoryEntity.setSettleTime(settleTime);
        settleHistoryEntity.setShopId(shopId);
        settleHistoryEntity.setTheLatestSettle(ConstantUtil.IS_THE_LATEST_SETTLE);
        settleHistoryEntity.setSettleOrderBeginTime(settleOrderBeginTime);
        settleHistoryEntity.setSettleOrderEndTime(settleOrderEndTime);
        settleHistoryEntity.setCurrentSettleAmount(MathUtil.decimal2Digits(createOrderMoney-refundMoney+useOrderMoeny, 2));
        settleHistoryEntity.setDealAmount(MathUtil.decimal2Digits(createOrderMoney, 2));
        settleHistoryEntity.setRefundAmount(MathUtil.decimal2Digits(refundMoney, 2));
        settleHistoryEntity.setOrderSettleTime(now);
        settleHistoryEntity.setVerificationAmount(MathUtil.decimal2Digits(useOrderMoeny, 2));

        settleHistoryService.save(settleHistoryEntity);


        // TODO 后续优化批量修改，或者通过队列去修改 TicketOrderItem 的状态
        for (TicketOrderItemEntity ticketOrderItemEntity : orderItemList4CreatedOrderSettle){
            TicketOrderItemEntity update = new TicketOrderItemEntity();
            update.setId(ticketOrderItemEntity.getId());
            update.setSettleTime(now);
            update.setSettleStatus(ConstantUtil.SETTLE_STATUS_COMMIT_ORDER);
            ticketOrderItemService.updateById(update);

            ticketOrderItemEntity.setSettleTime(now);
            ticketOrderItemEntity.setSettleStatus(ConstantUtil.SETTLE_STATUS_COMMIT_ORDER);

            // 保存记录到 TicketSettleEntity
            TicketSettleEntity ticketSettleEntity = new TicketSettleEntity();
            BeanUtils.copyProperties(ticketOrderItemEntity, ticketSettleEntity);
            ticketSettleEntity.setId(idGenerator.nextId());
            ticketSettleEntity.setSettleHistoryId(settleHistoryId);

            ticketSettleService.save(ticketSettleEntity);

        }
        for (TicketOrderItemEntity ticketOrderItemEntity : orderItemList4UseTicketSettle){
            TicketOrderItemEntity update = new TicketOrderItemEntity();
            update.setId(ticketOrderItemEntity.getId());
            update.setSettleTime(now);
            update.setSettleStatus(ConstantUtil.SETTLE_STATUS_USE);
            ticketOrderItemService.updateById(update);

            ticketOrderItemEntity.setSettleTime(now);
            ticketOrderItemEntity.setSettleStatus(ConstantUtil.SETTLE_STATUS_USE);

            // 保存记录到 TicketSettleEntity
            TicketSettleEntity ticketSettleEntity = new TicketSettleEntity();
            BeanUtils.copyProperties(ticketOrderItemEntity, ticketSettleEntity);
            ticketSettleEntity.setId(idGenerator.nextId());
            ticketSettleEntity.setSettleHistoryId(settleHistoryId);

            ticketSettleService.save(ticketSettleEntity);
        }
        for (TicketOrderItemEntity ticketOrderItemEntity : orderItemList4RefundOrder){
            TicketOrderItemEntity update = new TicketOrderItemEntity();
            update.setId(ticketOrderItemEntity.getId());
            update.setRefundSettleTime(now);
            update.setSettleStatus(ConstantUtil.SETTLE_STATUS_REFUND_ORDER);
            ticketOrderItemService.updateById(update);

            ticketOrderItemEntity.setRefundSettleTime(now);
            ticketOrderItemEntity.setSettleStatus(ConstantUtil.SETTLE_STATUS_REFUND_ORDER);

            // 保存记录到 TicketSettleEntity
            TicketSettleEntity ticketSettleEntity = new TicketSettleEntity();
            BeanUtils.copyProperties(ticketOrderItemEntity, ticketSettleEntity);
            ticketSettleEntity.setId(idGenerator.nextId());
            ticketSettleEntity.setSettleHistoryId(settleHistoryId);

            ticketSettleService.save(ticketSettleEntity);
        }

        return GenericResponse.ok();
    }




    public static void main(String[] args) {

        /*DateTime lastSettleDate = new DateTime(
                2017,
                4,
                24,
                23,
                59);


        Integer settleTime = 24;
        DateTime now = new DateTime();
        int nowMonthOfYear = now.getMonthOfYear();
        int nowYear = now.getYear();
        int nowDayOfMonth = now.getDayOfMonth();
        int settleMonthOfYear = lastSettleDate.getMonthOfYear();
        int settleYear = lastSettleDate.getYear();
        int settleDayOfMonth = lastSettleDate.getDayOfMonth();

        if(nowYear > settleYear){ //处理跨年
            if(nowMonthOfYear + 12 - settleMonthOfYear == 1){
                if(nowDayOfMonth > settleDayOfMonth){

                }else {
                    System.out.println("时间未到，不可以结算1111111");
                }
            }else if(nowMonthOfYear + 12 - settleMonthOfYear > 1){
                if(nowDayOfMonth > settleDayOfMonth){

                }else {
                    //上个月的时间
                    if(nowMonthOfYear == 1){
                        nowMonthOfYear = 12;
                        nowYear = nowYear - 1;
                    }else {
                        nowMonthOfYear = nowMonthOfYear - 1;
                    }
                }
            }else {
                System.out.println("时间未到，不可以结算22222222");
            }
        }else if(nowYear == settleYear){ // 处理同年
            if(nowMonthOfYear == settleMonthOfYear){
                //本月已结算
                System.out.println("本月已结算33333");
            }else if(nowMonthOfYear - settleMonthOfYear > 1){
                if(nowDayOfMonth > settleDayOfMonth){

                }else {
                    //上个月的时间
                    nowMonthOfYear = nowMonthOfYear - 1;
                }
            }else if(nowMonthOfYear - settleMonthOfYear == 1){
                if(nowDayOfMonth < settleDayOfMonth){
                    System.out.println("时间未到，不可以结算444444");
                }
            }else {
                System.out.println("结算时间未到，暂不能结算55555");
            }
        }

        //settleOrderBeginTime = lastSettleDate.getMillis();
        DateTime settleOrderEndTime = new DateTime(
                nowYear,
                nowMonthOfYear,
                settleTime,
                23,
                59);
        System.out.println("***************23452345*********************");

        System.out.println("lastSettleDate: " + lastSettleDate);
        System.out.println("settleOrderEndTime：" + settleOrderEndTime);*/
    }


    @ApiOperation(value = "更改订单状态（下单变为使用状态）", notes = "更改订单状态（下单变为使用状态）")
    @ApiResponses({ @ApiResponse(code = 200, response = GenericResponse.class, message = "更改订单状态（下单变为使用状态）") })
    @GetMapping(value = "/update2use", produces = { MediaType.APPLICATION_JSON_UTF8_VALUE })
    public ResponseEntity<?> updateOrderItem2Use(HttpServletRequest request, @RequestParam String orderItemId, @RequestParam Long createdTime,
                                             @RequestParam Long useTime) {
        TicketOrderItemEntity itemEntity = new TicketOrderItemEntity();
        itemEntity.setId(orderItemId);
        itemEntity.setCreateTime(createdTime);
        itemEntity.setUseTime(useTime);
        boolean updateFlag = ticketOrderItemService.updateById(itemEntity);
        if(updateFlag){
            return GenericResponse.ok();
        }
        return GenericResponse.ng("修改使用状态失败");
    }

    @ApiOperation(value = "更改订单状态（下单变为退款状态）", notes = "更改订单状态（下单变为退款状态）")
    @ApiResponses({ @ApiResponse(code = 200, response = GenericResponse.class, message = "更改订单状态（下单变为退款状态）") })
    @GetMapping(value = "/update2refund", produces = { MediaType.APPLICATION_JSON_UTF8_VALUE })
    public ResponseEntity<?> updateOrderItem2Refund(HttpServletRequest request, @RequestParam String orderItemId,
                                             @RequestParam Long refundTime) {
        TicketOrderItemEntity itemEntity = new TicketOrderItemEntity();
        itemEntity.setId(orderItemId);
        itemEntity.setRefundTime(refundTime);
        itemEntity.setPayState(PayState.REFUNDED.value());
        boolean updateFlag = ticketOrderItemService.updateById(itemEntity);
        if(updateFlag){
            return GenericResponse.ok();
        }
        return GenericResponse.ng("修改退款状态失败");
    }


}
